// (C) Copyright 2012 Kystar. All rights reserved.

`timescale 1ns/100ps
`default_nettype none

module VG903_G01
(
    // global signals
    input  wire         I_osc_25M, // 25M

    // video input
    input  wire         I_vin_pclk,
    input  wire         I_vin_vsync,
    input  wire         I_vin_de,
    input  wire [23: 0] I_vin_data,

    // RGMII
    output reg          phy_rst_n,
    output wire         mdc,
    inout  tri          mdio,

    output wire         rgmii_p0_txc,
    output wire         rgmii_p0_txen,
    output wire [ 3: 0] rgmii_p0_txd,
    output wire         rgmii_p1_txc,
    output wire         rgmii_p1_txen,
    output wire [ 3: 0] rgmii_p1_txd,

    input  wire         rgmii_p0_rxc,
    input  wire         rgmii_p0_rxdv,
    input  wire [ 3: 0] rgmii_p0_rxd,
    input  wire         rgmii_p1_rxc,
    input  wire         rgmii_p1_rxdv,
    input  wire [ 3: 0] rgmii_p1_rxd,

    // audio
    output wire         mclk,
    input  wire         lrck,
    input  wire         sck,
    input  wire         sda,

    // LEDs
    output wire         p0_led,
    output wire         p1_led,


    // sdm1 - external sdram 
    inout  wire [23:0]  sdm1_data,
    output reg [10:0]  sdm1_addr,
    //output wire [0:0]   sdm1_dqm,
    output reg [1:0]   sdm1_bank,
    output wire         sdm1_cas,
    output wire         sdm1_ras,
    output wire         sdm1_we,
    output wire         sdm1_clk,
    //output wire         sdm1_cs,

    // sdm2 - internal sdram
    inout  wire [23:0]  sdm2_data,
    output wire [10:0]  sdm2_addr,
    output wire [3:0]   sdm2_dqm,
    output wire [1:0]   sdm2_bank,
    output wire         sdm2_cas,
    output wire         sdm2_ras,
    output wire         sdm2_we,
    output wire         sdm2_clk,
    output wire         sdm2_cs,
    output wire         sdm2_cke,

    // spi interface
    output wire         mcu_mnt,
    input  wire         mcu_clk,
    input  wire         mcu_cs,
    input  wire         mcu_dat_in,
    output wire         mcu_dat_out,

    input  wire         flash_SO,
    input  wire         flash_SCK,
    input  wire         flash_SI,
    input  wire         flash_CS_n,

    // i2c
    output reg          O_dvi_hpd,
    input  wire         I_dvi_ddc_scl,
    inout  tri          B_dvi_ddc_sda

//		input	wire		JP202_PIN6
);
/******************************************************************************
                                调试
******************************************************************************/

//wire         I_vin_pclk;
//wire         I_vin_vsync;
//wire         I_vin_de;
//wire [23: 0] I_vin_data;

    // audio
//wire         mclk;
//wire         lrck;
//wire         sck;
//wire         sda;

/*    // sdm1 - internal sdram
wire [23:0]  sdm1_data;
reg [10:0]  sdm1_addr;
reg [1:0]   sdm1_bank;
wire         sdm1_cas;
wire         sdm1_ras;
wire         sdm1_we;
wire         sdm1_clk;
wire         sdm1_cs;
wire         sdm1_cke;

    // sdm2 - internal sdram
wire [23:0]  sdm2_data;
wire [10:0]  sdm2_addr;
wire [3:0]   sdm2_dqm;
wire [1:0]   sdm2_bank;
wire         sdm2_cas;
wire         sdm2_ras;
wire         sdm2_we;
wire         sdm2_clk;
wire         sdm2_cs;
wire         sdm2_cke;

    // spi interface
wire         mcu_mnt;
wire         mcu_clk;
wire         mcu_cs;
wire         mcu_dat_in;
wire         mcu_dat_out;

wire         flash_SO;
wire         flash_SCK;
wire         flash_SI;
wire         flash_CS_n;

    // i2c
reg          O_dvi_hpd;
wire         I_dvi_ddc_scl;
wire          B_dvi_ddc_sda;
*/
//*************************************************/
//assign	I_vin_pclk = 0;
//assign	I_vin_vsync = 0;
//assign	I_vin_de = 0;
//assign	I_vin_data = 0;

//assign	mclk = 0;
//assign	lrck = 0;
//assign	sck = 0;

/*
assign	mcu_clk = 0;
assign	mcu_cs = 0;
assign	mcu_dat_in = 0;

assign	flash_SO = 0;
assign	flash_SCK = 0;
assign	flash_SI = 0;
assign	flash_CS_n = 0;

assign	I_dvi_ddc_scl = 0;
*/
/******************************************************************************
                                <localparams>
******************************************************************************/
localparam [31:0]
    DATE           = 32'h19_07_09_20;

localparam // sdm2_arbi_state
    SDM2_ARBI_IDLE = 0,
    SDM2_ARBI_VIB = 1,
    SDM2_ARBI_P0 = 1<<1,
    SDM2_ARBI_P1 = 1<<2;

localparam // sdm1_arbi_state
    SDM1_ARBI_IDLE = 0,
    SDM1_ARBI_VIB = 1,
    SDM1_ARBI_P0 = 1<<1,
    SDM1_ARBI_P1 = 1<<2;

//程序版本信息
localparam [ 7: 0] 
    MAIN_FUNCTION  = "V",
    SUB_FUNCTION   = "G",
    MAIN_SOLUTION  = 8'd9,
    SUB_SOLUTION   = 8'h03,
    APP_TYPE       = "G",
    MAIN_VERSION   = 8'h01,
    SUB_VERSION    = 8'd1,
    MINI_VERSION   = 8'd5;

localparam
    MAX_VIN_WIDTH = 4100;

localparam
    FRAME1_START_ADDR = 512 * 1024 * 4 / 2;

localparam
    START_IDLE = 2'b00,
    START_DELAY = 2'b01,
    START_OK = 2'b10;

//******************************************************************/
//			   参数定义
//******************************************************************/
//程序版本信息
/*parameter	MAIN_FUNCTION	=  "L";		//ASCII "S"  
parameter	SUB_FUNCTION	=  "L";		//ASCII "L"  
parameter	MAIN_SOLUTION	=  9;		//"9"        
parameter	SUB_SOLUTION	=  2;		//"09"       
parameter	APPLICATION_TYPE=  "X";		//ASCII "G"  
parameter	MAIN_VERSION	=  8'd1;	//"03"       
parameter	SUB_VERSION	=  8'd1;	//"X01"
parameter	MINI_VERSION	=  8'd35;	//" "  
*/
//模块参数设置
defparam	main_ctrl.phy_comm.state_ctrl.main_function	=MAIN_FUNCTION;
defparam	main_ctrl.phy_comm.state_ctrl.sub_function	=SUB_FUNCTION;
defparam	main_ctrl.phy_comm.state_ctrl.main_solution	=MAIN_SOLUTION;
defparam	main_ctrl.phy_comm.state_ctrl.sub_solution	=SUB_SOLUTION;
defparam	main_ctrl.phy_comm.state_ctrl.application_type	=APP_TYPE;
defparam	main_ctrl.phy_comm.state_ctrl.main_version	=MAIN_VERSION;
defparam	main_ctrl.phy_comm.state_ctrl.sub_version	=SUB_VERSION;
defparam	main_ctrl.phy_comm.state_ctrl.mini_version	=MINI_VERSION;

defparam        main_ctrl.mcu_comm.main_function	=	MAIN_FUNCTION;
defparam        main_ctrl.mcu_comm.sub_function		=	SUB_FUNCTION;
defparam        main_ctrl.mcu_comm.main_solution	=	MAIN_SOLUTION;
defparam        main_ctrl.mcu_comm.sub_solution		=	SUB_SOLUTION;
defparam        main_ctrl.mcu_comm.application_type	=	APP_TYPE;
defparam        main_ctrl.mcu_comm.main_version		=	MAIN_VERSION;
defparam        main_ctrl.mcu_comm.sub_version		=	SUB_VERSION;
defparam        main_ctrl.mcu_comm.mini_version		=	MINI_VERSION;

/******************************************************************************
                              <internal signals>
******************************************************************************/
// clocks
wire         osc_25M;
wire         sclk;
wire         vin_pclk;
// resets
wire         rst_n;
// vib_top
wire         new_frame;
wire         vib_use_c1;
reg          send_disp_set_pkg_start;
reg  [ 2: 0] sdm1_arbi_state;
reg  [ 2: 0] next_sdm1_arbi_state;
reg  [ 2: 0] sdm2_arbi_state;
reg  [ 2: 0] next_sdm2_arbi_state;
//
reg  [ 6: 0] time0;
reg  [ 9: 0] time1;
reg  time0_is_127;

//--------------------------------------------------------------------
// memory
//--------------------------------------------------------------------
// req & ack
wire          sdm1_vib_req;
reg           sdm1_vib_ack;
wire          sdm1_vob_req_p0;
reg           sdm1_vob_ack_p0;
wire          sdm1_vob_req_p1;
reg           sdm1_vob_ack_p1;

wire          sdm2_vib_req;
reg           sdm2_vib_ack;
wire          sdm2_vob_req_p0;
reg           sdm2_vob_ack_p0;
wire          sdm2_vob_req_p1;
reg           sdm2_vob_ack_p1;
// sdram_ctrl
wire          sdm1_sdram_wr_rd_end;
wire          sdm1_sdram_wr_en;
wire          sdm1_sdram_rd_en;
wire [ 31: 0] sdm1_sdram_start_addr;
wire [ 15: 0] sdm1_sdram_length;
wire          sdm1_sdram_ask_for_data;
wire [ 23: 0] sdm1_sdram_wdata;
wire [ 23: 0] sdm1_sdram_rdata;
wire          sdm1_sdram_rdata_valid;
wire          sdm2_sdram_wr_rd_end;
wire          sdm2_sdram_wr_en;
wire          sdm2_sdram_rd_en;
wire [ 31: 0] sdm2_sdram_start_addr;
wire [ 15: 0] sdm2_sdram_length;
wire          sdm2_sdram_ask_for_data;
wire [ 23: 0] sdm2_sdram_wdata;
wire [ 23: 0] sdm2_sdram_rdata;
wire          sdm2_sdram_rdata_valid;
// vib
wire [ 31: 0] sdm1_sdram_start_addr_vib;
wire [ 31: 0] sdm2_sdram_start_addr_vib;
wire [ 15: 0] sdm1_sdram_length_vib;
wire [ 15: 0] sdm2_sdram_length_vib;
// p0
wire          sdm1_sdram_rd_en_p0;
wire          sdm2_sdram_rd_en_p0;
wire [ 31: 0] sdm1_sdram_start_addr_p0;
wire [ 31: 0] sdm2_sdram_start_addr_p0;
wire [ 15: 0] sdm1_sdram_length_p0;
wire [ 15: 0] sdm2_sdram_length_p0;
// p1
wire          sdm1_sdram_rd_en_p1;
wire          sdm2_sdram_rd_en_p1;
wire [ 31: 0] sdm1_sdram_start_addr_p1;
wire [ 31: 0] sdm2_sdram_start_addr_p1;
wire [ 15: 0] sdm1_sdram_length_p1;
wire [ 15: 0] sdm2_sdram_length_p1;

// phy check
reg  [16:0]  ms_cnt;
reg          ms_tick;
reg  [1:0]   start_state;
reg  [1:0]   next_start_state;
reg  [7:0]   delay_cnt;
wire         p0_rxc;
wire         p0_rxdv;
wire         p0_rxer;
wire         p1_rxc;
wire         p1_rxdv;
wire         p1_rxer;
wire         p0_error;
wire         p1_error;
reg  [3:0]   reset_phy_sync;
reg          check_phy;
reg  [13:0]  check_phy_timer;

// audio
wire audio_data_valid;
wire [ 7: 0] audio_data;

// EDID
wire [ 7: 0] dvi_edid_ram_addr;
wire [ 7: 0] dvi_edid_ram_q;
wire [7:0] edid_ram_addr_b;
reg  [ 14: 0] dvi_hpd_cnt;

// reboot to test
wire reboot_to_test_p0;
wire reboot_to_test_p1;
reg  reboot_to_test;
reg  [ 2: 0] reboot_to_test_cnt;
reg  reg_rb_need_reboot_to_test;

//--------------------------------------------------------------------
// registers
//--------------------------------------------------------------------
wire          action_wren;
wire          cfg_wren;
wire          edid_ram_wren;
wire [  3: 0] px_pkg_ram_wren;
wire [ 11: 0] waddr;
wire [  7: 0] wdata;
wire [ 11: 0] raddr;
wire          status_rden;
wire [  7: 0] status_rdata;
wire          action_rden;
wire [  7: 0] action_rdata;
wire          cfg_rden;
wire [  7: 0] cfg_rdata;
wire          edid_ram_rden;
wire [  7: 0] edid_ram_q_b;
reg  [  7: 0] edid_ram_rdata;
wire [  3: 0] px_pkg_ram_rden;
wire [  7: 0] p0_pkg_ram_rdata;
wire [  7: 0] p1_pkg_ram_rdata;
wire [  3: 0] px_comm_back_ram_rden;
wire [  7: 0] p0_comm_back_ram_rdata;
wire [  7: 0] p1_comm_back_ram_rdata;
//--------------------------------------------------------------------
// common
wire          reg_vib_enable;
wire [  7: 0] reg_nop_bytes;
wire [  8: 0] reg_frame_pkg_byte_num;
wire [ 10: 0] reg_disp_set_pkg_byte_num;
wire [ 11: 0] reg_idle_pkg_byte_num;
wire [ 11: 0] reg_comm_pkg_byte_num;
wire [ 12: 0] reg_rb_vin_width;
wire [ 12: 0] reg_rb_vin_height;
wire [ 12: 0] reg_rb_vin_width_to_pc;
wire [ 12: 0] reg_rb_vin_height_to_pc;
wire [  7: 0] reg_rb_vin_frame_rate;
wire          reg_rb_ddr3_err;
wire [ 23: 0] reg_reboot_addr;
wire          reg_reboot_en;
wire          reg_reset_ddr3;
wire          reg_rb_video_not_active;
wire          reg_px_send_comm_pkg;
wire          reg_px_enable;
wire [ 11: 0] reg_px_start_row_offset;
wire [ 11: 0] reg_px_start_col_offset;
wire [ 11: 0] reg_vin_max_width;
wire [ 11: 0] reg_vin_max_height;
wire          reg_mac_addr_incr_en;
wire [ 11: 0] reg_max_pixel_num_in_one_trans;
wire          reg_long_pkg_en;
wire          reg_reduced_pkg_en;
wire          reg_send_card_backup_en;
// p0
wire          reg_p0_enable;
wire [ 11: 0] reg_p0_start_row;
wire [ 11: 0] reg_p0_start_col;
wire [ 11: 0] reg_p0_width;
wire [ 11: 0] reg_p0_height;
wire          reg_p0_disable_disp_set_pkg;
wire          reg_p0_audio_enable;
wire [ 11: 0] reg_p0_line_step;
wire          reg_p0_send_comm_pkg;
wire          reg_p0_rb_comm_back_flag;
wire          reg_p0_rb_comm_back_crc_err;
wire [ 11: 0] reg_p0_rb_comm_back_length;
wire          reg_p0_clr_comm_back_flag;
wire          reg_p0_rb_sending_comm_pkg;
// p1
wire          reg_p1_enable;
wire [ 11: 0] reg_p1_start_row;
wire [ 11: 0] reg_p1_start_col;
wire [ 11: 0] reg_p1_width;
wire [ 11: 0] reg_p1_height;
wire          reg_p1_disable_disp_set_pkg;
wire          reg_p1_audio_enable;
wire [ 11: 0] reg_p1_line_step;
wire          reg_p1_send_comm_pkg;
wire          reg_p1_rb_comm_back_flag;
wire          reg_p1_rb_comm_back_crc_err;
wire [ 11: 0] reg_p1_rb_comm_back_length;
wire          reg_p1_clr_comm_back_flag;
wire          reg_p1_rb_sending_comm_pkg;

/******************************************************************************
                                <module body>
******************************************************************************/
//--------------------------------------------------------------------
// register access
//--------------------------------------------------------------------
//--------------------------------------------------------------------
// mcu_mnt
//--------------------------------------------------------------------
reg  [ 12: 0] tim_cnt;
reg	[4:0]	vin_a;

always @(posedge sclk)
	vin_a <= {vin_a[3:0], I_vin_vsync};

always @(posedge sclk or negedge rst_n)
    if(!rst_n)
        tim_cnt <= 13'h1000;
    else if(vin_a[4:3] == 2'b01)
        tim_cnt <= 13'h0000;
    else if(!tim_cnt[12])
        tim_cnt <= tim_cnt + 1'b1;

assign mcu_mnt = 0;

spi_top u_spi_top
(
    .I_sclk(sclk),
    .I_rst_n(rst_n),
    
    .I_mcu_clk(mcu_clk),
    .I_mcu_cs(mcu_cs),
    .I_mcu_dat_in(mcu_dat_in),
    .O_mcu_dat_out(mcu_dat_out),
    
    .O_action_wren(action_wren),
    .O_cfg_wren(cfg_wren),
    .O_edid_ram_wren(edid_ram_wren),
    .O_px_pkg_ram_wren(px_pkg_ram_wren),
    .O_waddr(waddr),
    .O_wdata(wdata),
    .O_raddr(raddr),
    .O_status_rden(status_rden),
    .I_status_rdata(status_rdata),
    .O_action_rden(action_rden),
    .I_action_rdata(action_rdata),
    .O_cfg_rden(cfg_rden),
    .I_cfg_rdata(cfg_rdata),
    .O_edid_ram_rden(edid_ram_rden),
    .I_edid_ram_rdata(edid_ram_rdata),
    .O_px_pkg_ram_rden(px_pkg_ram_rden),
    .I_p0_pkg_ram_rdata(p0_pkg_ram_rdata),
    .I_p1_pkg_ram_rdata(p1_pkg_ram_rdata),
    .I_p2_pkg_ram_rdata(),
    .I_p3_pkg_ram_rdata(),
    .O_px_comm_back_ram_rden(px_comm_back_ram_rden),
    .I_p0_comm_back_ram_rdata(p0_comm_back_ram_rdata),
    .I_p1_comm_back_ram_rdata(p1_comm_back_ram_rdata),
    .I_p2_comm_back_ram_rdata(),
    .I_p3_comm_back_ram_rdata()
);

regfile u_regfile
(
    .I_sclk(sclk),
    .I_rst_n(rst_n),
    .I_action_wren(action_wren),
    .I_cfg_wren(cfg_wren),
    .I_waddr(waddr),
    .I_wdata(wdata),
    .I_raddr(raddr),
    .I_status_rden(status_rden),
    .O_status_rdata(status_rdata),
    .I_action_rden(action_rden),
    .O_action_rdata(action_rdata),
    .I_cfg_rden(cfg_rden),
    .O_cfg_rdata(cfg_rdata),
    .I_reg_rb_main_function(MAIN_FUNCTION),
    .I_reg_rb_sub_function(SUB_FUNCTION),
    .I_reg_rb_main_solution(MAIN_SOLUTION),
    .I_reg_rb_sub_solution(SUB_SOLUTION),
    .I_reg_rb_app_type(APP_TYPE),
    .I_reg_rb_main_version(MAIN_VERSION),
    .I_reg_rb_sub_version(SUB_VERSION),
    .I_reg_rb_mini_version(MINI_VERSION),
    .I_reg_rb_date_year(DATE[31:24]),
    .I_reg_rb_date_month(DATE[23:16]),
    .I_reg_rb_date_day(DATE[15:8]),
    .I_reg_rb_date_clock(DATE[7:0]),
    .I_reg_rb_video_not_active(reg_rb_video_not_active),
    .I_reg_rb_vin_width(reg_rb_vin_width_to_pc),
    .I_reg_rb_vin_height(reg_rb_vin_height_to_pc),
    .I_reg_rb_vin_frame_rate(reg_rb_vin_frame_rate),
    .I_reg_rb_c1_calib_done(),
    .I_reg_rb_c3_calib_done(),
    .I_reg_rb_need_reboot_to_test(reg_rb_need_reboot_to_test),
    .I_reg_rb_ddr3_err(reg_rb_ddr3_err),
    .I_reg_p0_rb_comm_back_flag(reg_p0_rb_comm_back_flag),
    .I_reg_p0_rb_comm_back_crc_err(reg_p0_rb_comm_back_crc_err),
    .I_reg_p0_rb_comm_back_length(reg_p0_rb_comm_back_length),
    .I_reg_p0_rb_sending_comm_pkg(reg_p0_rb_sending_comm_pkg),
    .I_reg_p1_rb_comm_back_flag(reg_p1_rb_comm_back_flag),
    .I_reg_p1_rb_comm_back_crc_err(reg_p1_rb_comm_back_crc_err),
    .I_reg_p1_rb_comm_back_length(reg_p1_rb_comm_back_length),
    .I_reg_p1_rb_sending_comm_pkg(reg_p1_rb_sending_comm_pkg),
    .I_reg_p2_rb_comm_back_flag(),
    .I_reg_p2_rb_comm_back_crc_err(),
    .I_reg_p2_rb_comm_back_length(),
    .I_reg_p2_rb_sending_comm_pkg(),
    .I_reg_p3_rb_comm_back_flag(),
    .I_reg_p3_rb_comm_back_crc_err(),
    .I_reg_p3_rb_comm_back_length(),
    .I_reg_p3_rb_sending_comm_pkg(),
    .O_reg_reboot_addr(),
    .O_reg_reboot_en(reg_reboot_en),
    .O_sc_reg_reset_ddr3(reg_reset_ddr3),
    .O_reg_vib_enable(reg_vib_enable),
    .O_reg_px_enable(reg_px_enable),
    .O_sc_reg_px_send_comm_pkg(reg_px_send_comm_pkg),
    .O_sc_reg_p0_send_comm_pkg(reg_p0_send_comm_pkg),
    .O_sc_reg_p0_clr_comm_back_flag(reg_p0_clr_comm_back_flag),
    .O_sc_reg_p1_send_comm_pkg(reg_p1_send_comm_pkg),
    .O_sc_reg_p1_clr_comm_back_flag(reg_p1_clr_comm_back_flag),
    .O_sc_reg_p2_send_comm_pkg(),
    .O_sc_reg_p2_clr_comm_back_flag(),
    .O_sc_reg_p3_send_comm_pkg(),
    .O_sc_reg_p3_clr_comm_back_flag(),
    .O_reg_nop_bytes(reg_nop_bytes),
    .O_reg_frame_pkg_byte_num(reg_frame_pkg_byte_num),
    .O_reg_disp_set_pkg_byte_num(reg_disp_set_pkg_byte_num),
    .O_reg_idle_pkg_byte_num(reg_idle_pkg_byte_num),
    .O_reg_comm_pkg_byte_num(reg_comm_pkg_byte_num),
    .O_reg_mac_addr_incr_en(reg_mac_addr_incr_en),
    .O_reg_max_pixel_num_in_one_trans(reg_max_pixel_num_in_one_trans),
    .O_reg_long_pkg_en(reg_long_pkg_en),
    .O_reg_px_start_row_offset(reg_px_start_row_offset),
    .O_reg_px_start_col_offset(reg_px_start_col_offset),
    .O_reg_vin_max_width(reg_vin_max_width),
    .O_reg_vin_max_height(reg_vin_max_height),
    .O_reg_reduced_pkg_en(reg_reduced_pkg_en),
    .O_reg_send_card_backup_en(reg_send_card_backup_en),
    .O_reg_p0_enable(reg_p0_enable),
    .O_reg_p0_start_row(reg_p0_start_row),
    .O_reg_p0_start_col(reg_p0_start_col),
    .O_reg_p0_width(reg_p0_width),
    .O_reg_p0_height(reg_p0_height),
    .O_reg_p0_disable_disp_set_pkg(reg_p0_disable_disp_set_pkg),
    .O_reg_p0_hori_invert_en(),
    .O_reg_p0_vert_invert_en(),
    .O_reg_p0_audio_enable(reg_p0_audio_enable),
    .O_reg_p0_line_step(reg_p0_line_step),
    .O_reg_p1_enable(reg_p1_enable),
    .O_reg_p1_start_row(reg_p1_start_row),
    .O_reg_p1_start_col(reg_p1_start_col),
    .O_reg_p1_width(reg_p1_width),
    .O_reg_p1_height(reg_p1_height),
    .O_reg_p1_disable_disp_set_pkg(reg_p1_disable_disp_set_pkg),
    .O_reg_p1_audio_enable(reg_p1_audio_enable),
    .O_reg_p1_line_step(reg_p1_line_step)
);

//******************************************************************/
//			   信号定义
//******************************************************************/
wire	[20:0]	time_us, sync_us;

wire		rec_flag_a, rec_flag, rec_error, send_flag, pre_flag;
wire	[7:0]	rec_data, send_data, phy_state;
wire 	[1:0]	force_send, rec_vendor;
wire		input_L9, redu_flag, blank_flag;

wire	[1:0]	depth_state;
wire	[9:0]	current_depth;

wire	[31:0]	phy_tout, main_tout;

//**************************************************************/
//			时钟和复位
//**************************************************************/
wire         init_pll;
reg  [ 5: 0] reset_init = 6'b0 /* synthesis syn_preserve = 1*/;

clock_ctrl u_clock_ctrl(
    .inclk(I_osc_25M),
    .outclk(osc_25M)
);

sys_pll pll(
    .areset(!init_pll),
    .inclk0(osc_25M),
    .c0(sclk),
    .c1()
);

assign init_pll = reset_init[5];

always @(posedge osc_25M)
    if (!init_pll)
        reset_init <= reset_init + 1'b1;

sys_reset_ctrl sys_reset_ctrl(
    .sclkin(osc_25M),
    .resetb(rst_n)
);

//慢速分频时钟
sys_timer       sys_timer(
	.resetb(rst_n),
	.sclk(sclk),
	
        //分频时钟
        .time_us(time_us),
        .sync_us(sync_us)
	);

/*
sys_reset_clk sys_reset_clk(
		//输入时钟
		.sclkin(I_osc_25M),

		//输出复位和时钟
		.resetb(rst_n),
		.sclk(sclk),
		.oclk(),
		.sa_clk(),
		.clk_25M(osc_25M),

		//分频时钟
		.time_us(time_us),
		.sync_us(sync_us),

		//按键检测
		.pll_reset(2'b00),
		.pll_lock(),

		//调试信号	
		.tout()
		);
*/

//**************************************************************/
//			通讯模块
//**************************************************************/
phy_interface phy_interface(
		.resetb(rst_n),
		.sclk(sclk),
                
		.sync_16ms(sync_us[14]),

		//其他外部相关信号
		.sub_mode(1'b0),//sub_mode),
		.cas_depth_adj(depth_state[1]),
		.local_depth(current_depth[7:0]),

		.tx_err_en(1'b0),

		//PORTA接口
		.gp0_rxc(rgmii_p0_rxc),
		.gp0_rxdv(rgmii_p0_rxdv),
		.gp0_rxd(rgmii_p0_rxd),
		.gp0_txc(rgmii_p0_txc),
		.gp0_txen(rgmii_p0_txen),
		.gp0_txd(rgmii_p0_txd),
		
		//PORTB接口
		.gp1_rxc(rgmii_p1_rxdv),
		.gp1_rxdv(rgmii_p1_rxdv),
		.gp1_rxd(rgmii_p1_rxd),
		.gp1_txc(rgmii_p1_txc),
		.gp1_txen(rgmii_p1_txen),
		.gp1_txd(rgmii_p1_txd),
		
		//内部的接收接口
		.rec_flag_a(rec_flag_a),
		.rec_flag(rec_flag),
		.rec_data(rec_data),
		.rec_error(rec_error),
		.rec_error_sync(),
		
		//内部的发送接口
		.force_send(force_send),
		.send_flag(send_flag),
		.pre_flag(pre_flag),
		.send_data(send_data),

		//给内部的其他信号
		.input_port(),//input_port),
		.rec_vendor(rec_vendor),
		.yt_vs_pre(),//yt_vs_pre),
		.input_active(input_L9),
		.redu_flag(redu_flag),
		.blank_flag(blank_flag),
		.phy_state(phy_state),
		
		.tout(phy_tout)
		);
		
		
//**************************************************************
//			FPGA主控逻辑
//**************************************************************
main_ctrl main_ctrl(
		//复位时钟，按键，Led
		.resetb(rst_n),
		.sclk(sclk),

		.time_us(time_us),
		.sync_us(sync_us),
		
		//按键和指示灯
		.key_in(1'b0),
		.led_g(),//led_g),

`ifdef H611
		//Flash接口
		.flash_CS_n(flash_CS_n),
		.flash_SCK(flash_SCK),
		.flash_SI(flash_SI),
		.flash_SO(flash_SO),

		//PHY配置接口
		.phy_rst(phy_rst),
		.phy_mdc(phy_mdc),
		.phy_mdio(phy_mdio),

		//冗余控制信号
		.device_main(device_main),
`endif

                //外部MCU通讯接口
		.mcu_fpga_ctrl(1'b0),//mcu_fpga_ctrl),
		
		.mcu_spi_fpga(1'b0),//mcu_spi_fpga),
		.mcu_spi_clk(1'b0),//mcu_spi_clk),
		.mcu_spi_mosi(1'b0),//mcu_spi_mosi),
		.mcu_spi_miso(),//mcu_spi_miso),

		.spi2_cs(),//spi2_cs),
		.spi2_clk(),//spi2_clk),
		.spi2_mosi(),//spi2_mosi),

		//PHY通讯接口
		.sub_mode(),//sub_mode),
		.depth_state(depth_state),
		.current_depth(current_depth),

		.input_L9(input_L9),
		.phy_state(phy_state),
		.redu_flag(redu_flag),
		.blank_flag(blank_flag),
		.rec_vendor(rec_vendor),
		
		.rec_flag_a(rec_flag_a),
		.rec_flag(rec_flag),
		.rec_data(rec_data),
		.rec_error(rec_error),
		.rec_error_sync(),
		
		.force_send(force_send),
		.send_flag(send_flag),
		.pre_flag(pre_flag),
		.send_data(send_data),
		
		//PHY总线接口
		.init_mode(),//init_mode),
		.set_d_ok(),//set_d_ok),
		.ext_d_ok(),//ext_d_ok),
		.set_addr(),//set_addr),
		.set_data(),//set_data),
		.rd_data(),//rd_data),
		.debug_data(),//debug_data),

		//MCU总线接口
		.mcu_set_d_ok(),//mcu_set_d_ok),
		.mcu_ext_d_ok(),//mcu_ext_d_ok),
		.mcu_set_addr(),//mcu_set_addr),
		.mcu_set_data(),//mcu_set_data),
		.mcu_rd_data(8'h00),//mcu_rd_hub),

		//L9显示数据接口
		.vs_L9(),//vs_L9),
		.ds_L9(),//ds_L9),
		.data_L9(),//data_L9),
		.h_start_L9(),//h_start_L9),
		.h_num_L9(),//h_num_L9),
		.l2048_mode(),//l2048_mode),

		.state(),//state),
		.color_restore_type(),//color_restore_type),
		.testmode(),//testmode),
		.cascade_light(),//cascade_light),

		//Artnet显示数据接口
		.input_artnet(),//input_artnet),
		.ds_a(),//ds_a),
		.data_a(),//data_a),
		.h_start_a(),//h_start_a),
		.h_num_a(),//h_num_a),

		//背板控制接口
		.device_port(),//device_port),
		.fpga_dmx_send(1'b0),//dmx_send_flag),
		.mcu_dmx_ten(),//mcu_dmx_ten),
		
		//SD卡MCU控制接口
		.mcu_sd_en(),//mcu_sd_en),
		.mcu_sd_miso(1'b0),//mcu_sd_miso),
		
		//SD发送数据包接口
		.force_send_play(1'b0),//force_send_play),
		.send_flag_dis(1'b0),//send_flag_sd),
		.pre_flag_dis(1'b0),//pre_flag_sd),
		.send_data_dis(8'h0),//send_data_sd),

		//SD卡状态
		.sd_state(8'h0),//sd_state),
		
		//调试接口
		.tout(main_tout)   
		);

//--------------------------------------------------------------------
// vib_top
//--------------------------------------------------------------------
//vin_pclk_pll u_vin_pclk_pll(
//    .areset(!init_pll),
//    .inclk0(I_vin_pclk),
//    .c0(vin_pclk),
//    .locked()
//);

assign vin_pclk = I_vin_pclk;

vib_top
#(
    .MAX_VIN_WIDTH(MAX_VIN_WIDTH),
    .FRAME1_START_ADDR(FRAME1_START_ADDR)
)
u_vib_top
(
    .I_sclk(sclk),
    .I_rst_n(rst_n/* && !reg_reset_ddr3*/),
    .I_vin_pclk(vin_pclk),
    .I_vin_vsync(I_vin_vsync),
    .I_vin_de(I_vin_de),
    .I_vin_data(I_vin_data),
    .O_vin_led(),//p1_led),
    .O_new_frame(new_frame),
    .O_vib_use_c1(vib_use_c1),
    .O_sdm1_vib_req(sdm1_vib_req),
    .I_sdm1_vib_ack(sdm1_vib_ack),
    .I_sdm1_sdram_wr_rd_end(sdm1_sdram_wr_rd_end),
    .O_sdm1_sdram_wr_en(sdm1_sdram_wr_en),
    .O_sdm1_sdram_start_addr(sdm1_sdram_start_addr_vib),
    .O_sdm1_sdram_length(sdm1_sdram_length_vib),
    .I_sdm1_sdram_ask_for_data(sdm1_sdram_ask_for_data),
    .O_sdm1_sdram_wdata(sdm1_sdram_wdata),
    .O_sdm2_vib_req(sdm2_vib_req),
    .I_sdm2_vib_ack(sdm2_vib_ack),
    .I_sdm2_sdram_wr_rd_end(sdm2_sdram_wr_rd_end),
    .O_sdm2_sdram_wr_en(sdm2_sdram_wr_en),
    .O_sdm2_sdram_start_addr(sdm2_sdram_start_addr_vib),
    .O_sdm2_sdram_length(sdm2_sdram_length_vib),
    .I_sdm2_sdram_ask_for_data(sdm2_sdram_ask_for_data),
    .O_sdm2_sdram_wdata(sdm2_sdram_wdata),
    .I_reg_vib_enable(reg_vib_enable),
    .O_reg_rb_vin_width(reg_rb_vin_width),
    .O_reg_rb_vin_height(reg_rb_vin_height),
    .O_reg_rb_vin_width_to_pc(reg_rb_vin_width_to_pc),
    .O_reg_rb_vin_height_to_pc(reg_rb_vin_height_to_pc),
    .O_reg_rb_vin_frame_rate(reg_rb_vin_frame_rate),
    .O_reg_rb_video_not_active(reg_rb_video_not_active),
    .O_reg_rb_ddr3_err(reg_rb_ddr3_err),
    .I_reg_px_start_row_offset(reg_px_start_row_offset),
    .I_reg_px_start_col_offset(reg_px_start_col_offset),
    .I_reg_vin_max_width(reg_vin_max_width),
    .I_reg_vin_max_height(reg_vin_max_height)

);

//--------------------------------------------------------------------
// p0 output
//--------------------------------------------------------------------
net_top
#(
    .MAX_VIN_WIDTH(MAX_VIN_WIDTH),
    .FRAME1_START_ADDR(FRAME1_START_ADDR)
)
u_net_top_p0
(
    .I_sclk(sclk),
    .I_rst_n(rst_n/* && !reg_reset_ddr3*/),
    .I_new_frame(new_frame),
    .I_video_not_active(reg_rb_video_not_active),
    .I_send_disp_set_pkg_start(send_disp_set_pkg_start),
    .I_vib_use_c1(vib_use_c1),
    .O_rgmii_txc(),
    .O_rgmii_txen(),
    .O_rgmii_txd(),
    .I_rgmii_rxc(1'b0),
    .I_rgmii_rxdv(1'b0),
    .I_rgmii_rxd(4'h0),
    .O_px_rxc(p0_rxc),
    .O_px_rxdv(p0_rxdv),
    .O_px_rxer(p0_rxer),
    .O_sdm1_vob_req(sdm1_vob_req_p0),
    .I_sdm1_vob_ack(sdm1_vob_ack_p0),
    .I_sdm1_sdram_wr_rd_end(sdm1_sdram_wr_rd_end),
    .O_sdm1_sdram_rd_en(sdm1_sdram_rd_en_p0),
    .O_sdm1_sdram_start_addr(sdm1_sdram_start_addr_p0),
    .O_sdm1_sdram_length(sdm1_sdram_length_p0),
    .I_sdm1_sdram_rdata(sdm1_sdram_rdata),
    .I_sdm1_sdram_rdata_valid(sdm1_sdram_rdata_valid),
    .O_sdm2_vob_req(sdm2_vob_req_p0),
    .I_sdm2_vob_ack(sdm2_vob_ack_p0),
    .I_sdm2_sdram_wr_rd_end(sdm2_sdram_wr_rd_end),
    .O_sdm2_sdram_rd_en(sdm2_sdram_rd_en_p0),
    .O_sdm2_sdram_start_addr(sdm2_sdram_start_addr_p0),
    .O_sdm2_sdram_length(sdm2_sdram_length_p0),
    .I_sdm2_sdram_rdata(sdm2_sdram_rdata),
    .I_sdm2_sdram_rdata_valid(sdm2_sdram_rdata_valid),
    .I_reg_rb_vin_width(reg_rb_vin_width),
    .I_reg_send_card_backup_en(reg_send_card_backup_en),
    .I_reg_px_enable(reg_p0_enable && reg_px_enable),
    .I_reg_nop_bytes(reg_nop_bytes),
    .I_reg_frame_pkg_byte_num(reg_frame_pkg_byte_num),
    .I_reg_disable_disp_set_pkg(reg_p0_disable_disp_set_pkg),
    .I_reg_disp_set_pkg_byte_num(reg_disp_set_pkg_byte_num),
    .I_reg_idle_pkg_byte_num(reg_idle_pkg_byte_num),
    .I_reg_send_comm_pkg(reg_p0_send_comm_pkg | reg_px_send_comm_pkg),
    .I_reg_comm_pkg_byte_num(reg_comm_pkg_byte_num),
    .I_reg_px_start_row(reg_p0_start_row),
    .I_reg_px_start_col(reg_p0_start_col),
    .I_reg_px_width(reg_p0_width),
    .I_reg_px_height(reg_p0_height),
    .I_reg_clr_comm_back_flag(reg_p0_clr_comm_back_flag),
    .O_reg_rb_comm_back_flag(reg_p0_rb_comm_back_flag),
    .O_reg_rb_comm_back_crc_err(reg_p0_rb_comm_back_crc_err),
    .O_reg_rb_comm_back_length(reg_p0_rb_comm_back_length),
    .O_reg_rb_sending_comm_pkg(reg_p0_rb_sending_comm_pkg),
    .I_reg_px_start_row_offset(12'd0/*reg_px_start_row_offset*/),
    .I_reg_px_start_col_offset(12'd0/*reg_px_start_col_offset*/),
    .I_reg_mac_addr_incr_en(1'b0/*reg_mac_addr_incr_en*/),
    .I_reg_max_pixel_num_in_one_trans(reg_max_pixel_num_in_one_trans),
    .I_reg_long_pkg_en(1'b0/*reg_long_pkg_en*/),
    .I_reg_px_line_step(reg_p0_line_step),
    .I_reg_px_hori_invert_en(1'b0),
    .I_reg_px_vert_invert_en(1'b0),
    .I_reg_px_audio_enable(reg_p0_audio_enable),
    .I_reg_reduced_pkg_en(reg_reduced_pkg_en),
    .I_pkg_ram_wen(px_pkg_ram_wren[0]),
    .I_pkg_ram_waddr(waddr),
    .I_pkg_ram_wdata(wdata),
    .I_pkg_ram_rden(px_pkg_ram_rden[0]),
    .I_pkg_ram_raddr(raddr),
    .O_pkg_ram_rdata(p0_pkg_ram_rdata),
    .I_comm_back_ram_ren(px_comm_back_ram_rden[0]),
    .I_comm_back_ram_raddr(raddr[10:0]),
    .O_comm_back_ram_rdata(p0_comm_back_ram_rdata),
    .I_audio_data_valid(audio_data_valid),
    .I_audio_data(audio_data),
    .O_reboot_to_test(reboot_to_test_p0)
);

//--------------------------------------------------------------------
// p1 output
//--------------------------------------------------------------------
net_top
#(
    .MAX_VIN_WIDTH(MAX_VIN_WIDTH),
    .FRAME1_START_ADDR(FRAME1_START_ADDR)
)
u_net_top_p1
(
    .I_sclk(sclk),
    .I_rst_n(rst_n/* && !reg_reset_ddr3*/),
    .I_new_frame(new_frame),
    .I_vib_use_c1(vib_use_c1),
    .I_video_not_active(reg_rb_video_not_active),
    .I_send_disp_set_pkg_start(send_disp_set_pkg_start),
    .O_rgmii_txc(),
    .O_rgmii_txen(),
    .O_rgmii_txd(),
    .I_rgmii_rxc(1'b0),
    .I_rgmii_rxdv(1'b0),
    .I_rgmii_rxd(4'h0),
    .O_px_rxc(p1_rxc),
    .O_px_rxdv(p1_rxdv),
    .O_px_rxer(p1_rxer),
    .O_sdm1_vob_req(sdm1_vob_req_p1),
    .I_sdm1_vob_ack(sdm1_vob_ack_p1),
    .I_sdm1_sdram_wr_rd_end(sdm1_sdram_wr_rd_end),
    .O_sdm1_sdram_rd_en(sdm1_sdram_rd_en_p1),
    .O_sdm1_sdram_start_addr(sdm1_sdram_start_addr_p1),
    .O_sdm1_sdram_length(sdm1_sdram_length_p1),
    .I_sdm1_sdram_rdata(sdm1_sdram_rdata),
    .I_sdm1_sdram_rdata_valid(sdm1_sdram_rdata_valid),
    .O_sdm2_vob_req(sdm2_vob_req_p1),
    .I_sdm2_vob_ack(sdm2_vob_ack_p1),
    .I_sdm2_sdram_wr_rd_end(sdm2_sdram_wr_rd_end),
    .O_sdm2_sdram_rd_en(sdm2_sdram_rd_en_p1),
    .O_sdm2_sdram_start_addr(sdm2_sdram_start_addr_p1),
    .O_sdm2_sdram_length(sdm2_sdram_length_p1),
    .I_sdm2_sdram_rdata(sdm2_sdram_rdata),
    .I_sdm2_sdram_rdata_valid(sdm2_sdram_rdata_valid),
    .I_reg_rb_vin_width(reg_rb_vin_width),
    .I_reg_send_card_backup_en(reg_send_card_backup_en),
    .I_reg_px_enable(reg_p1_enable && reg_px_enable),
    .I_reg_nop_bytes(reg_nop_bytes),
    .I_reg_frame_pkg_byte_num(reg_frame_pkg_byte_num),
    .I_reg_disable_disp_set_pkg(reg_p1_disable_disp_set_pkg),
    .I_reg_disp_set_pkg_byte_num(reg_disp_set_pkg_byte_num),
    .I_reg_idle_pkg_byte_num(reg_idle_pkg_byte_num),
    .I_reg_send_comm_pkg(reg_p1_send_comm_pkg | reg_px_send_comm_pkg),
    .I_reg_comm_pkg_byte_num(reg_comm_pkg_byte_num),
    .I_reg_px_start_row(reg_p1_start_row),
    .I_reg_px_start_col(reg_p1_start_col),
    .I_reg_px_width(reg_p1_width),
    .I_reg_px_height(reg_p1_height),
    .I_reg_clr_comm_back_flag(reg_p1_clr_comm_back_flag),
    .O_reg_rb_comm_back_flag(reg_p1_rb_comm_back_flag),
    .O_reg_rb_comm_back_crc_err(reg_p1_rb_comm_back_crc_err),
    .O_reg_rb_comm_back_length(reg_p1_rb_comm_back_length),
    .O_reg_rb_sending_comm_pkg(reg_p1_rb_sending_comm_pkg),
    .I_reg_px_start_row_offset(12'd0/*reg_px_start_row_offset*/),
    .I_reg_px_start_col_offset(12'd0/*reg_px_start_col_offset*/),
    .I_reg_mac_addr_incr_en(1'b0/*reg_mac_addr_incr_en*/),
    .I_reg_max_pixel_num_in_one_trans(reg_max_pixel_num_in_one_trans),
    .I_reg_long_pkg_en(1'b0/*reg_long_pkg_en*/),
    .I_reg_px_line_step(reg_p1_line_step),
    .I_reg_px_hori_invert_en(1'b0),
    .I_reg_px_vert_invert_en(1'b0),
    .I_reg_px_audio_enable(reg_p1_audio_enable),
    .I_reg_reduced_pkg_en(reg_reduced_pkg_en),
    .I_pkg_ram_wen(px_pkg_ram_wren[1]),
    .I_pkg_ram_waddr(waddr),
    .I_pkg_ram_wdata(wdata),
    .I_pkg_ram_rden(px_pkg_ram_rden[1]),
    .I_pkg_ram_raddr(raddr),
    .O_pkg_ram_rdata(p1_pkg_ram_rdata),
    .I_comm_back_ram_ren(px_comm_back_ram_rden[1]),
    .I_comm_back_ram_raddr(raddr[10:0]),
    .O_comm_back_ram_rdata(p1_comm_back_ram_rdata),
    .I_audio_data_valid(audio_data_valid),
    .I_audio_data(audio_data),
    .O_reboot_to_test(reboot_to_test_p1)
);

//--------------------------------------------------------------------
// state machine : sdm1_arbi_state
//--------------------------------------------------------------------
always @(posedge sclk or negedge rst_n)
    if (!rst_n)
        sdm1_arbi_state <= SDM1_ARBI_IDLE;
    else
        sdm1_arbi_state <= next_sdm1_arbi_state;

always @(*)
    case (sdm1_arbi_state)
        SDM1_ARBI_IDLE:
            if (sdm1_vib_req)
                next_sdm1_arbi_state = SDM1_ARBI_VIB;
            else if (sdm1_vob_req_p0)
                next_sdm1_arbi_state = SDM1_ARBI_P0;
            else if (sdm1_vob_req_p1)
                next_sdm1_arbi_state = SDM1_ARBI_P1;
            else
                next_sdm1_arbi_state = SDM1_ARBI_IDLE;
        SDM1_ARBI_VIB:
            if (!sdm1_vib_req)
                next_sdm1_arbi_state = SDM1_ARBI_IDLE;
            else
                next_sdm1_arbi_state = SDM1_ARBI_VIB;
        SDM1_ARBI_P0:
            if (!sdm1_vob_req_p0)
                next_sdm1_arbi_state = SDM1_ARBI_IDLE;
            else
                next_sdm1_arbi_state = SDM1_ARBI_P0;
        SDM1_ARBI_P1:
            if (!sdm1_vob_req_p1)
                next_sdm1_arbi_state = SDM1_ARBI_IDLE;
            else
                next_sdm1_arbi_state = SDM1_ARBI_P1;
        default:
            next_sdm1_arbi_state = SDM1_ARBI_IDLE;
    endcase

always @(posedge sclk or negedge rst_n)
    if (!rst_n)
        sdm1_vib_ack <= 1'b0;
    else
        sdm1_vib_ack <= sdm1_arbi_state == SDM1_ARBI_VIB;

always @(posedge sclk or negedge rst_n)
    if (!rst_n)
        sdm1_vob_ack_p0 <= 1'b0;
    else
        sdm1_vob_ack_p0 <= sdm1_arbi_state == SDM1_ARBI_P0;

always @(posedge sclk or negedge rst_n)
    if (!rst_n)
        sdm1_vob_ack_p1 <= 1'b0;
    else
        sdm1_vob_ack_p1 <= sdm1_arbi_state == SDM1_ARBI_P1;

assign sdm1_sdram_rd_en = sdm1_vob_ack_p0 ? sdm1_sdram_rd_en_p0 : sdm1_sdram_rd_en_p1;
assign sdm1_sdram_start_addr = sdm1_vib_ack ? sdm1_sdram_start_addr_vib : (sdm1_vob_ack_p0 ? sdm1_sdram_start_addr_p0 : sdm1_sdram_start_addr_p1);
assign sdm1_sdram_length = sdm1_vib_ack ? sdm1_sdram_length_vib : (sdm1_vob_ack_p0 ? sdm1_sdram_length_p0 : sdm1_sdram_length_p1);

//--------------------------------------------------------------------
// state machine : sdm2_arbi_state
//--------------------------------------------------------------------
always @(posedge sclk or negedge rst_n)
    if (!rst_n)
        sdm2_arbi_state <= SDM2_ARBI_IDLE;
    else
        sdm2_arbi_state <= next_sdm2_arbi_state;

always @(*)
    case (sdm2_arbi_state)
        SDM2_ARBI_IDLE:
            if (sdm2_vib_req)
                next_sdm2_arbi_state = SDM2_ARBI_VIB;
            else if (sdm2_vob_req_p0)
                next_sdm2_arbi_state = SDM2_ARBI_P0;
            else if (sdm2_vob_req_p1)
                next_sdm2_arbi_state = SDM2_ARBI_P1;
            else
                next_sdm2_arbi_state = SDM2_ARBI_IDLE;
        SDM2_ARBI_VIB:
            if (!sdm2_vib_req)
                next_sdm2_arbi_state = SDM2_ARBI_IDLE;
            else
                next_sdm2_arbi_state = SDM2_ARBI_VIB;
        SDM2_ARBI_P0:
            if (!sdm2_vob_req_p0)
                next_sdm2_arbi_state = SDM2_ARBI_IDLE;
            else
                next_sdm2_arbi_state = SDM2_ARBI_P0;
        SDM2_ARBI_P1:
            if (!sdm2_vob_req_p1)
                next_sdm2_arbi_state = SDM2_ARBI_IDLE;
            else
                next_sdm2_arbi_state = SDM2_ARBI_P1;
        default:
            next_sdm2_arbi_state = SDM2_ARBI_IDLE;
    endcase

always @(posedge sclk or negedge rst_n)
    if (!rst_n)
        sdm2_vib_ack <= 1'b0;
    else
        sdm2_vib_ack <= sdm2_arbi_state == SDM2_ARBI_VIB;

always @(posedge sclk or negedge rst_n)
    if (!rst_n)
        sdm2_vob_ack_p0 <= 1'b0;
    else
        sdm2_vob_ack_p0 <= sdm2_arbi_state == SDM2_ARBI_P0;

always @(posedge sclk or negedge rst_n)
    if (!rst_n)
        sdm2_vob_ack_p1 <= 1'b0;
    else
        sdm2_vob_ack_p1 <= sdm2_arbi_state == SDM2_ARBI_P1;

assign sdm2_sdram_rd_en = sdm2_vob_ack_p0 ? sdm2_sdram_rd_en_p0 : sdm2_sdram_rd_en_p1;
assign sdm2_sdram_start_addr = sdm2_vib_ack ? sdm2_sdram_start_addr_vib : (sdm2_vob_ack_p0 ? sdm2_sdram_start_addr_p0 : sdm2_sdram_start_addr_p1);
assign sdm2_sdram_length = sdm2_vib_ack ? sdm2_sdram_length_vib : (sdm2_vob_ack_p0 ? sdm2_sdram_length_p0 : sdm2_sdram_length_p1);

//--------------------------------------------------------------------
// SDRAM
//--------------------------------------------------------------------
sdram_ctl #(
    .ROW_WTH(11),
    .COL_WTH(8),
    .BANK_WTH(2),
    .DATA_WTH(32)
) u_sdram_ctl_1 (
    //system signals
    .sclk(sclk),
    .sclk_shift(sclk),
    .rst_n(rst_n),
    //interface with internal logic
    .sdram_initializing(),
    .wr_en(sdm1_sdram_wr_en),
    .rd_en(sdm1_sdram_rd_en),
    .wr_rd_end(sdm1_sdram_wr_rd_end),
    .start_addr(sdm1_sdram_start_addr),
    .length(sdm1_sdram_length),
    .ask_for_data(sdm1_sdram_ask_for_data),
    .data_in(sdm1_sdram_wdata),
    .data_out(sdm1_sdram_rdata),
    .data_out_valid(sdm1_sdram_rdata_valid),
    // interface with SDRAM
    .sdram_cke(),
    .sdram_cs_n(/*sdm1_cs*/),
    .sdram_ras_n(sdm1_ras),
    .sdram_cas_n(sdm1_cas),
    .sdram_we_n(sdm1_we),
    .sdram_clk(sdm1_clk),
    .sdram_bank(),//sdm1_bank),
    .sdram_addr(),//sdm1_addr),
    .sdram_dqm(/*sdm1_dqm*/),
    .sdram_data(sdm1_data)
);

sdram_ctl #(
    .ROW_WTH(11),
    .COL_WTH(8),
    .BANK_WTH(2),
    .DATA_WTH(32)
) u_sdram_ctl_2 (
    //system signals
    .sclk(sclk),
    .sclk_shift(sclk),
    .rst_n(rst_n),
    //interface with internal logic
    .sdram_initializing(),
    .wr_en(sdm2_sdram_wr_en),
    .rd_en(sdm2_sdram_rd_en),
    .wr_rd_end(sdm2_sdram_wr_rd_end),
    .start_addr(sdm2_sdram_start_addr),
    .length(sdm2_sdram_length),
    .ask_for_data(sdm2_sdram_ask_for_data),
    .data_in(sdm2_sdram_wdata),
    .data_out(sdm2_sdram_rdata),
    .data_out_valid(sdm2_sdram_rdata_valid),
    // interface with SDRAM
    .sdram_cke(sdm2_cke),
    .sdram_cs_n(sdm2_cs),
    .sdram_ras_n(sdm2_ras),
    .sdram_cas_n(sdm2_cas),
    .sdram_we_n(sdm2_we),
    .sdram_clk(sdm2_clk),
    .sdram_bank(sdm2_bank),
    .sdram_addr(sdm2_addr),
    .sdram_dqm(/*sdm2_dqm*/),
    .sdram_data(sdm2_data)
);

assign sdm2_dqm = 'd0;

//--------------------------------------------------------------------
// AR8035
//--------------------------------------------------------------------
AR8035_top u_AR8035_top(
    .sclk(osc_25M), 
    .rst_n(phy_rst_n),   
    .mdc(mdc),
    .mdio(mdio)
);

// phy check
always @(posedge sclk or negedge rst_n) begin
    if (!rst_n)
        ms_cnt <= 17'd124999;
    else if (ms_tick)
        ms_cnt <= 17'd124999;
    else
        ms_cnt <= ms_cnt - 1'b1;
end

always @(posedge sclk or negedge rst_n) begin
    if (!rst_n)
        ms_tick <= 1'b0;
    else if (ms_cnt == 1'b1)
        ms_tick <= 1'b1;
    else
        ms_tick <= 1'b0;
end

always @(posedge sclk or negedge rst_n) begin
    if (!rst_n)
        start_state <= START_IDLE;
    else if (reset_phy_sync[3:2] == 2'b01)
        start_state <= START_IDLE;
    else
        start_state <= next_start_state;
end

always @(*) begin
    case (start_state)
        START_IDLE:
            next_start_state = START_DELAY;
        START_DELAY:
            if (delay_cnt >= 8'd100)
                next_start_state = START_OK;
            else
                next_start_state = START_DELAY;
        START_OK:
            next_start_state = START_OK;
        default:
            next_start_state = START_IDLE;
    endcase
end

always @(posedge sclk or negedge rst_n) begin
    if (!rst_n)
        delay_cnt <= 1'b0;
    else if (start_state == START_IDLE)
        delay_cnt <= 1'b0;
    else
        delay_cnt <= delay_cnt  + 1'b1;
end

always @(posedge sclk or negedge rst_n) begin
    if (!rst_n)
        phy_rst_n <= 1'b0;
    else if (start_state == START_OK)
        phy_rst_n <= 1'b1;
    else
        phy_rst_n <= 1'b0;
end

always @(posedge sclk) begin
    reset_phy_sync <= {reset_phy_sync[2:0], p0_error | p1_error};
end

always @(posedge sclk or negedge rst_n) begin
    if (!rst_n)
        check_phy <= 1'b0;
    else if (reset_phy_sync[3:2] == 2'b01)
        check_phy <= 1'b0;
    else if (check_phy_timer == 1'b0)
        check_phy <= 1'b1;
end

always @(posedge sclk or negedge rst_n) begin
    if (!rst_n)
        check_phy_timer <= 14'd10000; // 启动前10秒不监测phy
    else if (reset_phy_sync[3:2] == 2'b01)
        check_phy_timer <= 14'd10000; // 复位phy10秒内不监测phy
    else if (ms_tick && check_phy_timer != 1'b0)
        check_phy_timer <= check_phy_timer - 1'b1;
end

// px_check
px_check p0_check (
    .I_sclk    ( sclk ),
    .I_rst_n   ( check_phy ),
    .I_ms_tick ( ms_tick ),
    .I_rxc     ( p0_rxc ),
    .I_rxdv    ( p0_rxdv ),
    .I_rxer    ( p0_rxer ),
    .O_error   ( p0_error )
);

// px_check
px_check p1_check (
    .I_sclk    ( sclk ),
    .I_rst_n   ( check_phy ),
    .I_ms_tick ( ms_tick ),
    .I_rxc     ( p1_rxc ),
    .I_rxdv    ( p1_rxdv ),
    .I_rxer    ( p1_rxer ),
    .O_error   ( p1_error )
);

//--------------------------------------------------------------------
// audio_input
//--------------------------------------------------------------------
audio_input u_audio_input
(
    .I_sclk(sclk),
    .I_clk_25m(osc_25M),
    .mclk(mclk),
    .lrck(lrck),
    .sck(sck),
    .sda(sda),
    .O_audio_data(audio_data),
    .O_audio_data_valid(audio_data_valid)
);

//------------------------------------------------------------------
// EDID
//------------------------------------------------------------------
i2c_slave #( .DEV_ADDR(7'b1010_000)) u_i2c_slave_dvi(
    .sclk(osc_25M),
    .rst_n(rst_n),
    .scl(I_dvi_ddc_scl),
    .sda(B_dvi_ddc_sda),
    .wr_en(),
    .wr_data(),
    .addr(dvi_edid_ram_addr),
    .rd_data(dvi_edid_ram_q)
);

dvi_edid_ram u_dvi_edid_ram(
    .address_a(dvi_edid_ram_addr),
    .address_b(edid_ram_addr_b),
    .clock_a(osc_25M),
    .clock_b(sclk),
    .data_a(8'd0),
    .data_b(wdata),
    .wren_a(1'b0),
    .wren_b(edid_ram_wren & (waddr[11:8] == 4'd0)),
    .q_a(dvi_edid_ram_q),
    .q_b(edid_ram_q_b)
);

always @(posedge sclk or negedge rst_n)
    if (!rst_n)
        O_dvi_hpd <= 1'b1;
    else
        O_dvi_hpd <= ~dvi_hpd_cnt[14];

always @(posedge sclk or negedge rst_n)
    if (!rst_n)
        dvi_hpd_cnt <= 'd0;
    else if (edid_ram_wren)
        dvi_hpd_cnt <= 'd0;
    else if (time0_is_127 & (!dvi_hpd_cnt[14]))
        dvi_hpd_cnt <= dvi_hpd_cnt + 1'b1;

assign edid_ram_addr_b = edid_ram_wren ? waddr[7:0] : raddr[7:0];

always @(posedge sclk)
    if (edid_ram_rden)
        edid_ram_rdata <= edid_ram_q_b;

//--------------------------------------------------------------------
// LED
//--------------------------------------------------------------------
always @(posedge sclk)
    time0 <= time0 + 1'b1;

always @(posedge sclk)
    time0_is_127 <= time0 == 127;

always @(posedge sclk)
    if (time1 == 1023)
        time1 <= 'd0;
    else if (time0_is_127)
        begin
        time1 <= time1 + 1'b1;
        end

always @(posedge sclk)
    if (send_disp_set_pkg_start)
        send_disp_set_pkg_start <= 1'b0;
    else if (reg_send_card_backup_en)
        send_disp_set_pkg_start <= 1'b0;
    else if (reg_rb_video_not_active && time1 == 1023)
        send_disp_set_pkg_start <= 1'b1;
        
//assign p0_led = 1'b0;

//--------------------------------------------------------------------
// reboot
//--------------------------------------------------------------------
wire reboot_o_osc;

always @(posedge sclk or negedge rst_n)
    if (!rst_n)
        reboot_to_test <= 1'b0;
    else
        reboot_to_test <= reboot_to_test_p0 | reboot_to_test_p1;

always @(posedge sclk or negedge rst_n)
    if (!rst_n)
        reboot_to_test_cnt <= 'd0;
    else if (new_frame)
        reboot_to_test_cnt <= 'd0;
    else if (reboot_to_test)
        begin
        if (!reboot_to_test_cnt[2])
            reboot_to_test_cnt <= reboot_to_test_cnt + 1'b1;
        end

always @(posedge sclk or negedge rst_n)
    if (!rst_n)
        reg_rb_need_reboot_to_test <= 1'b0;
    else
        reg_rb_need_reboot_to_test <= reboot_to_test_cnt[2];

alta_boot reboot(
    .i_boot(reg_reboot_en),
    .im_vector_sel('d1),
    .i_osc_enb(1'b1),
    .o_osc(reboot_o_osc)
);


//******************************************
//		调试信号
//******************************************
assign	p0_led = send_flag;//main_tout[0];
assign	p1_led = send_data[0];//main_tout[1];

always @(posedge sclk) begin
	sdm1_bank[1:0] <= main_tout[3:2];
	sdm1_addr[10] <= main_tout[4];
	sdm1_addr[2:0] <= main_tout[7:5];
	sdm1_addr[9:3] <= send_data[6:0];
	end

endmodule
`default_nettype wire

